import signal
from signal import SIGCHLD, SIGTERM, SIGINT, SIGQUIT, SIG_DFL, SIG_IGN
import multiprocessing
from multiprocessing import Process
from typing import Callable
from data import processes
import sys
from functools import partial
import time

counts = 4

def run(process):
    while True:
        print(f"{process} running...")
        time.sleep(1)

def h2(process: Process):
    print(f"kill {process}")
    process.terminate()

def monitor(process: Process, func: Callable):
    for signame in [SIGTERM, SIGCHLD, SIGINT, SIGQUIT]: 
        # No SIGCHILD is not trigger singnal_handler, 
        # No SIGINT is not handler ctrl+c, 
        # No SIGQUIT is RuntimeError: reentrant call inside <_io.BufferedWriter name='<stdout>'>  
        signal.signal(signame, partial(signal_handler, process, func))

def signal_handler(process: Process, func, signum, frame):
    print(f"{signum=}")
    global counts

    if signum == 17: # 17 is SIGTERM
        # 这个循环是为了忽略SIGCHILD 发出的信号，避免抢占了主进程发出的SIGTERM 
        for signame in [SIGTERM, SIGCHLD, SIGQUIT]:
            signal.signal(signame, SIG_DFL)
        print("Restarting run_process")
        p4 = multiprocessing.Process(target=func, args=(f"p{counts}",))
        p4.start()
        monitor(p4, run)
        processes["case100"] = p4
        counts += 1

    if signum == 2:
        if process.is_alive():
            print(f"Kill {process} process")
            process.terminate()
        signal.signal(SIGCHLD, SIG_IGN)
        sys.exit("kill parent process")
